package org.zhangyp.n02datastructure.n01Array;

import java.util.Arrays;

/**
 * 数组相关练习
 *
 * @author zhangyp
 * @date 2023/6/7 10:41
 */
public class ArrayDemo {
    /**
     * 打印 int 数组
     *
     * @param: nums
     * @return: void
     * @author: zhangyp
     * @date: 2023/6/8 9:51
     **/
    public void printArray(int[] nums) {
        System.out.print("[");
        for (int index = 0; index < nums.length; index++) {
            System.out.print(nums[index]);
            if (index < nums.length - 1) {
                System.out.print(",");
            } else {
                System.out.print("]");
            }
        }
        System.out.println("");
    }

    /**
     * 把数组中的 0 移到末尾
     * For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
     *
     * @param: nums
     * @return: void
     * @author: zhangyp
     * @date: 2023/6/8 9:33
     **/
    public void moveZeroes(int[] nums) {
        int index = 0;
        for (int num : nums) {
            if (num != 0) {
                nums[index] = num;
                index = index + 1;
            }
        }
        while (index < nums.length) {
            nums[index] = 0;
            index = index + 1;
        }
    }

    /**
     * 改变数组维度，改为r行c列
     *
     * @param: nums
     * @param: r
     * @param: c
     * @return: int[][]
     * @author: zhangyp
     * @date: 2023/6/12 9:24
     **/
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int m = nums.length, n = nums[0].length;
        if (m * n != r * c) {
            return nums;
        }
        int[][] result = new int[r][c];
        // 遍历原数组
        int index = 0;
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                result[i][j] = nums[index / n][index % n];
                index++;
            }
        }
        return result;
    }

    /**
     * 整型数组按个位值排序
     * 给定一个非空数组(列表)，其元素数据类型为整型，请按照数组元素十进制最低位从小到大进行排序，十进制最低位相同的元素，相对位置保持不变
     * 当数组元素为负值时，十进制最低位等同于去除符号位后对应十进制值最低位。
     * <p>
     * 解题思路：直接将数字转为字符串，然后取字符串的最后一个字符进行排序，排序直接使用java的排序，java的排序为归并排序，是一种稳定的排序算法
     *
     * @param nums
     * @return
     */
    public int[] singleSigitsSort(int[] nums) {
        String[] strNums = new String[nums.length];
        for (int i = 0; i < nums.length; i++) {
            strNums[i] = Integer.toString(nums[i]);
        }
        // 自定义排序
        //Arrays.sort(strNums, Comparator.comparing(s -> s.substring(s.length() - 1)));
        //Arrays.stream(strNums).sorted(Comparator.comparing(s -> s.substring(s.length() - 1)));

        for (int i = 0; i < strNums.length; i++) {
            nums[i] = Integer.parseInt(strNums[i]);
        }
        return nums;
    }


    /**
     * 计算围棋的气
     *
     * @param black 黑色棋子
     * @param white 白色棋子
     * @return
     */
    public String calculateTheQi(int[] black, int[] white) {
        // 创建一张棋盘，棋盘中0表示没有棋子，1表示有黑棋，2表示有白棋
        int[][] chessboard = new int[19][19];
        setVal(chessboard, black, 1);
        setVal(chessboard, white, 2);

        int blackRes = getQi(chessboard, black);

        int whiteRes = getQi(chessboard, white);

        return blackRes + " " + whiteRes;
    }

    private void setVal(int[][] chessboard, int[] chess, int val) {
        for (int i = 0; i < chess.length / 2; i++) {
            int x = chess[2 * i];
            int y = chess[2 * i + 1];
            chessboard[x][y] = val;
        }
    }

    private int getQi(int[][] chessboard, int[] chess) {
        int[][] resultArr = new int[19][19];
        for (int i = 0; i < chess.length / 2; i++) {
            int x = chess[2 * i];
            int y = chess[2 * i + 1];
            // 上
            if (y > 0 && chessboard[x][y - 1] == 0) {
                resultArr[x][y - 1] = 1;
            }
            // 下
            if (y < 18 && chessboard[x][y + 1] == 0) {
                resultArr[x][y + 1] = 1;
            }
            // 左
            if (x > 0 && chessboard[x - 1][y] == 0) {
                resultArr[x - 1][y] = 1;
            }
            // 右
            if (x < 18 && chessboard[x + 1][y] == 0) {
                resultArr[x + 1][y] = 1;
            }
        }
        int result = 0;
        for (int[] ress : resultArr) {
            for (int res : ress) {
                result += res;
            }
        }
        return result;
    }

    public int removeElement(int[] nums, int val) {
        int index = 0;
        for (int num : nums) {
            if (num != val) {
                nums[index] = num;
                index++;
            }
        }
        return index;
    }

    /**
     * 统计数组中的美丽分割
     *
     * @param nums
     * @return
     */
    public int beautifulSplits(int[] nums) {
        int res = 0;
        int len = nums.length;
        // 尝试1是2的前缀
        for (int i = 0; i < len - 1; i++) {
            boolean isPrefix1 = false; //1是2是否是前缀
            // 第一段超过数组的一半，已不可能再有前缀
            if ((i + 1) * 2 <= (len - 1)) {
                if (isPrefix(nums, 0, i, i + 1, i + 1 + i)) {
                    res += len - 2 * (i + 1);
                    isPrefix1 = true;
                }
            }
            // 尝试2是3的前缀
            int len2 = len - i - 1; //第2、3段的总长度
            int end = isPrefix1 ? (i + 1) * 2 - 1 : len; //防止重复划分（在12前缀的情况下，23的前缀只可能出现在2段之内）
            for (int j = i + 1; j < end; j++) {
                // 第一段超过数组的一半，已不可能再有前缀
                if ((j - i - 1) * 2 > len2) {
                    break;
                }
                if (isPrefix(nums, i + 1, j, j + 1, len - 1)) {
                    res += 1;
                }
            }
        }
        return res;
    }

    private boolean isPrefix(int[] nums, int start1, int end1, int start2, int end2) {
        if (end2 - start2 < end1 - start1) {
            return false;
        }
        for (int i = 0; i <= end1 - start1; i++) {
            if (nums[start1 + i] != nums[start2 + i]) {
                return false;
            }
        }
        return true;
    }


    /**
     * 数字分组求偶数和
     *
     * @param numbers
     * @return
     */
    public static int solution(int[] numbers) {
        // 使用一个二维数组来装所有的组合
        String[] targetArr = {""};
        for (int num : numbers) {
            String str = Integer.toString(num);
            // 将本组数字拆分，拼接到原来的每一个数字上
            String[] newTargetArr = new String[str.length() * targetArr.length];
            int i = 0;
            for (char c : str.toCharArray()) {
                for (String target : targetArr) {
                    String newTarget = target + c;
                    newTargetArr[i++] = newTarget;
                }
            }
            targetArr = newTargetArr;
        }
        // 遍历所有组合，计算偶数的个数
        int result = 0;
        System.out.println(Arrays.toString(targetArr));
        for (String target : targetArr) {
            int sum = 0;
            for (char c : target.toCharArray()) {
                sum += c - '0';
            }
            if (sum % 2 == 0) {
                result++;
            }
        }
        return result;
    }


    public static void main(String[] args) {
        /*int[] nums = {0, 1, 0, 3, 12};
        ArrayDemo demo = new ArrayDemo();
        demo.moveZeroes(nums);
        demo.printArray(nums);*/
        /*int[][] nums = {{0, 1, 0, 3, 12}, {1, 3, 0, 5, 9}, {6, 7, 9, 3, 6}};
        ArrayDemo demo = new ArrayDemo();
        int[][] result = demo.matrixReshape(nums, 5, 3);
        for (int[] row : result) {
            demo.printArray(row);
        }*/


        /*int[] num1 = {0, 5, 8, 9, 9, 10};
        int[] num2 = {5, 0, 9, 9, 9, 8};
        ArrayDemo demo = new ArrayDemo();
        String result = demo.calculateTheQi(num1, num2);
        System.out.println(result);*/
        /*long start = System.currentTimeMillis();
        int[] nums = {5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2, 5, 5, 4, 2};
        ArrayDemo demo = new ArrayDemo();
        int res = demo.beautifulSplits(nums);
        System.out.println("res= " + res + "   耗时：" + (System.currentTimeMillis() - start) + "ms");*/

        // You can add more test cases here
        System.out.println(solution(new int[]{123, 456, 789}) == 14);
        System.out.println(solution(new int[]{123456789}) == 4);
        System.out.println(solution(new int[]{14329, 7568}) == 10);
    }


}
